#include "pch.h"
#include "PostRenderer.h"

namespace mini
{
	CPostRenderer::CPostRenderer(CDevice* pDevice)
		: CRenderer(pDevice)
		, mSwapIndex(0)
	{
		mRenderTypeFlag = RendererType::PostRenderer;
		CMaterialUnit* pMaterialUnit = new CMaterialUnit;
		pMaterialUnit->setUnitFile(R"(resource\Material\airEffect.ma)");
		pMaterialUnit->onInitialise();
		mpMaterialUnit = pMaterialUnit;
		int nWidth = pDevice->getConfig().screenWidth;
		int nHeight = pDevice->getConfig().screenHeight;
		int nBackBufferCount = 2;
		for (int i = 0; i < nBackBufferCount; ++i)
		{
			CTexture* pTexture = new CTexture();
			if (nullptr != pTexture)
			{
				pTexture->initialiseRenderTexture(nWidth, nHeight, DXGI_FORMAT_R8G8B8A8_UNORM);
				pTexture->setSampleState(pMaterialUnit->getSampler(0));
				pMaterialUnit->setTexture(pTexture, i);
				mTextureArray.push_back(pTexture);
				mpRenderTargetViewArray.push_back(mTextureArray[0]->getRenderTargetView());
			}
		}

		mpMeshUnit = GEngine->createBillBoard(nWidth, nHeight);

		mpMeshUnit->bindMaterial(mpMaterialUnit);
	}

	void CPostRenderer::useTarget()
	{
		mpDeferredContext->OMSetRenderTargets(1, &mpRenderTargetViewArray[mSwapIndex], nullptr);
		mpDeferredContext->PSSetShaderResources(0, 1, &mpCurrentShaderRV);

	}

	void CPostRenderer::swapTarget()
	{
		GEngine->getDevice()->recoverBackBuffer(mpDeferredContext);
		auto pMaterialUnit = mpMeshUnit->getMaterialUnit();
		auto pShaderUnit = pMaterialUnit->getShaderUnit(0);
		mTextureArray[mSwapIndex]->commitToGpu(mpDeferredContext, 0);
		pShaderUnit->setWorldMatrix(&mpMeshUnit->getMatrix());
		pShaderUnit->setViewMatrix(GEngine->getViewMatrix());
		pShaderUnit->setOrthoMatrix(GEngine->getOrthoMatrix());
		pShaderUnit->setShader(mpDeferredContext);
		pShaderUnit->apply(mpDeferredContext);
		mpMeshUnit->render(mpDeferredContext);

		++mSwapIndex;
	}

	CPostRenderer::~CPostRenderer()
	{
		SafeRelease(mpMaterialUnit);
		SafeRelease(mpMeshUnit);
		for (auto item : mTextureArray)
		{
			SafeRelease(item);
		}
		mTextureArray.clear();
		mpRenderTargetViewArray.clear();
	}

	void CPostRenderer::commitToGpu()
	{		
		//for (auto item : mTextureArray)
		//{
		//	item->clearRenderTargetView(CPoint4F(0, 0, 0, 0));
		//}
		//mpCurrentShaderRV = GEngine->getDevice()->getMainTargetShaderRV();
		//mTextureArray[0]->copyFrom(GEngine->getDevice()->getBackBufferTexture2D());
		for (auto item : mAttchEffects)
		{
		//	useTarget();
			(item.second)->commitToGpu(mpDeferredContext);
		//	swapTarget();
		}
	}

}
